package {
    import flash.display.Sprite;
    import flash.display.CapsStyle;
    import flash.display.JointStyle;
    import flash.display.LineScaleMode;

    public class Meter extends Sprite {
	
	protected var __width: int;
	protected var __height: int;

	protected var __maxValue : Number;
	protected var __value : Number;

	protected var __marks : Boolean;
	protected var __numMarks : int;

	protected var __backColor : int;
	protected var __foreColor : int;
	protected var __markColor : int;

	protected var __direction : int;
	protected var __rounding : Boolean;

	public static const LEFT_TO_RIGHT:int = 1;
	public static const RIGHT_TO_LEFT:int = 2;
	public static const TOP_TO_BOTTOM:int = 3;
	public static const BOTTOM_TO_TOP:int = 4;
	protected static const UNASSIGNED:int = 5;

	public function Meter() {
	    __width = 50;
	    __height = 10;
	    __maxValue = 1;
	    __value = 0.5;
	    __marks = false;
	    __numMarks = 9;
	    __direction = UNASSIGNED;
	    __rounding = true;
	    __backColor = 0x0000cc;
	    __foreColor = 0xcccc00;
	    __markColor = 0xcc0000;

	    redraw();
	}

	public function redraw() : void {
	    graphics.clear();
	    if (__direction == UNASSIGNED) {
		if (__width > __height) {
		    drawHorizontal(0,__width*__value/__maxValue);
		} else {
		    drawVertical(__height,__height*(1-__value/__maxValue));
		}
	    } else if (__direction == TOP_TO_BOTTOM) {
		drawVertical(0,__height*__value/__maxValue);
	    } else if (__direction == BOTTOM_TO_TOP) {
		drawVertical(__height,__height*(1-__value/__maxValue));
	    } else if (__direction == LEFT_TO_RIGHT) {
		drawHorizontal(0,__width*__value/__maxValue);
	    } else /* right to left */ {
		drawHorizontal(__width,__width*(1-__value/__maxValue));
	    }
	}
	
	protected function drawVertical(start:int,end:int) : void {
	    var capStyle : String;
	    if (__rounding) {
		capStyle = CapsStyle.ROUND;
	    } else {
		capStyle = CapsStyle.NONE;
	    }
	    graphics.lineStyle(__width,__backColor,1.0,true,
			       LineScaleMode.NORMAL, capStyle,
			       JointStyle.MITER);
	    graphics.moveTo(__width/2,0);
	    graphics.lineTo(__width/2,__height);
	    
	    graphics.lineStyle(Math.min(__width*19/20,__width-2),
			       __foreColor,1.0,true,LineScaleMode.NORMAL,
			       capStyle,JointStyle.MITER);
	    graphics.moveTo(__width/2,start);
	    graphics.lineTo(__width/2,end);

	    graphics.lineStyle(1,__markColor,1.0,true,LineScaleMode.NORMAL,
			       CapsStyle.NONE, JointStyle.MITER);
	    for (var i:int = 0; i<__numMarks; i++) {
		var loc : int = (i+1)*__height/(numMarks+1);
		graphics.moveTo(0,loc);
		graphics.lineTo(__width-1,loc);
	    }
	}

	protected function drawHorizontal(start:int,end:int) : void {
	    var capStyle : String;
	    if (__rounding) {
		capStyle = CapsStyle.ROUND;
	    } else {
		capStyle = CapsStyle.NONE;
	    }
	    graphics.lineStyle(__height,__backColor,1.0,true,
			       LineScaleMode.NORMAL, capStyle,
			       JointStyle.MITER);
	    graphics.moveTo(0,__height/2);
	    graphics.lineTo(__width,__height/2);
	    
	    graphics.lineStyle(Math.min(__height*19/20,__height-2),
			       __foreColor,1.0,true,LineScaleMode.NORMAL,
			       capStyle,JointStyle.MITER);
	    graphics.moveTo(start,__height/2);
	    graphics.lineTo(end,__height/2);

	    graphics.lineStyle(1,__markColor,1.0,true,LineScaleMode.NORMAL,
			       CapsStyle.NONE, JointStyle.MITER);
	    for (var i:int = 0; i<__numMarks; i++) {
		var loc : int = (i+1)*__width/(numMarks+1);
		graphics.moveTo(loc,0);
		graphics.lineTo(loc,__height-1);
	    }
	}
	 
	public function set rounding(newValue : Boolean) : void {
	    if (rounding != newValue) {
		__rounding = newValue;
		redraw();
	    }
	}

	public function get rounding() : Boolean {
	    return __rounding;
	}

	public function set direction(newDir:int) : void {
	    if ((1 <= newDir) && (newDir <= 5)) {
		__direction = newDir;
		redraw();
	    }
	}

	public function set backColor(newColor:int) : void {
	    __backColor = newColor;
	    redraw();
	}

	public function get backColor() : int {
	    return __backColor;
	}

	public function set foreColor(newColor:int) : void {
	    __foreColor = newColor;
	    redraw();
	}

	public function get foreColor() : int {
	    return __foreColor;
	}

	public function set markColor(newColor:int) : void {
	    __markColor = newColor;
	    redraw();
	}

	public function get markColor() : int {
	    return __markColor;
	}

	public function set meterWidth(newWidth:int) : void {
	    __width = newWidth;
	    redraw();
	}
	
	public function get meterWidth() : int {
	    return __width;
	}

	public function set meterHeight(newHeight:int) : void {
	    __height = newHeight;
	    redraw();
	}
	
	public function get meterHeight() : int {
	    return __height;
	}

	public function set maxValue(newValue:Number) : void {
	    __maxValue = newValue;
	    redraw();
	}
	
	public function get maxValue() : Number {
	    return __maxValue;
	}

	public function set value(newValue:Number) : void {
	    __value = newValue;
	    redraw();
	}
	
	public function get value() : Number {
	    return __value;
	}

	public function set marks(haveMarks:Boolean) : void {
	    if (__marks != haveMarks) {
		__marks = haveMarks;
		redraw();
	    }
	}
	
	public function get marks() : Boolean {
	    return __marks;
	}

	public function set numMarks(newNum:int) : void {
	    __numMarks = newNum;
	    redraw();
	}
	
	public function get numMarks() : int {
	    return __numMarks;
	}
    }
}